package com.zl.learning.db.redisson;

import org.junit.Test;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.api.listener.MessageListener;
import org.redisson.config.Config;

import java.io.Serializable;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RedissonTest {
    private static class SomeObject implements Serializable {
        int age = 10;
        String name = "zhangsan";

        @Override
        public String toString() {
            return "SomeObject{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    private static RedissonClient redisson;

    static {
        Config config = new Config();
        config.useSingleServer()
                // use "rediss://" for SSL connection
                .setAddress("redis://172.31.4.247:6379");
        redisson = Redisson.create(config);
    }

    @Test
    public void testMap() {
        RMap<String, SomeObject> map = redisson.getMap("anyMap");
        SomeObject prevObject = map.put("123", new SomeObject());
        System.out.println(prevObject);
        SomeObject currentObject = map.putIfAbsent("323", new SomeObject());
        System.out.println(currentObject);
        SomeObject obj = map.remove("123");
        System.out.println(obj);
        map.fastPut("321", new SomeObject());
        map.fastRemove("321");

        RFuture<SomeObject> putAsyncFuture = map.putAsync("321", new SomeObject());
//        RFuture<Void> fastPutAsyncFuture = map.fastPutAsync("321", new SomeObject());

        map.fastPutAsync("321", new SomeObject());
        map.fastRemoveAsync("321");
    }

    @Test
    public void testLockMap() {
        RMap<Integer, String> map = redisson.getMap("anyMap");
        final boolean aaa = map.fastPut(2, "aaa");
        System.out.println(aaa);
        Integer k = 1;
        RReadWriteLock keyLock = map.getReadWriteLock(k);
        keyLock.writeLock();
        try {
            String v = map.get(k);
            System.out.println(v);
            // 其他业务逻辑
        } finally {
            keyLock.writeLock().unlock();
        }

        RReadWriteLock rwLock = map.getReadWriteLock(k);
        rwLock.readLock().lock();
        try {
            String v = map.get(k);
            System.out.println(v);
            // 其他业务逻辑
        } finally {
            keyLock.readLock().unlock();
        }
    }

    static class TestBlockingQueue {
        public static void main(String[] args) {
            RBlockingQueue<String> queue = redisson.getBlockingQueue("anyQueue");
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            executorService.submit(() -> {
                boolean start = true;
                while (start) {
                    String val = null;
                    try {
                        val = queue.take();
                    } catch (InterruptedException e) {
                        start = false;
                    }
                    System.out.println(val);
                }
            });

            Scanner scanner = new Scanner(System.in);
            String s;
            while (!"exit".equals(s = scanner.nextLine())) {
                queue.add(s);
            }
            executorService.shutdownNow();
            redisson.shutdown();
        }
    }

    static class TestTopic {
        public static void main(String[] args) throws InterruptedException {
            RTopic topic1 = redisson.getTopic("topic1");
            int listenerId = topic1.addListener(String.class, new MessageListener<String>() {
                @Override
                public void onMessage(CharSequence channel, String msg) {
                    System.out.println(msg);
                }
            });
            topic1.publish("HelloWorld");
        }
    }

    @Test
    public void test1() {
        final RMap<Integer, String> anyMap = redisson.getMap("anyMap");
        System.out.println(anyMap.get(2));
//        RBlockingQueue<Integer> queue = redisson.getBlockingQueue("anyQueue");
//        queue.offer(1);
//
//        Integer obj = queue.peek();
//        System.out.println(obj);
//        Integer someObj = queue.poll();
//        System.out.println(someObj);
//        try {
//            Integer ob = queue.poll(10, TimeUnit.MINUTES);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }
}
